<template>
	<view class="calendarWrap" v-show="isShow">
		<!-- 时间切换区域 -->
		<view class="top">
			<view class="prev"></view>
			<text>{{dataObj.showTime}}</text>
			<view class="next"></view>
		</view>
		<!-- 详细日数据 -->
		<view class="dateWrap">
			<!-- 表头 -->
			<view class="header">
				<text class="block" v-for="(item, index) in headerData" :key="index">{{item.value}}</text>
			</view>
			<!-- 数据 -->
			<view class="content">
				<view :class="{'block':true,'placeholder':item.placeholder,'redDot':item.redDot,'isActive':item.active}"
					v-for="(item, index) in dataObj.calendar" :key="index"
					@click="item.placeholder?noClickData():clickData(item, index)">
					<text>{{item.day}}</text>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		name: "calendar",
		data() {
			return {
				dataObj: {
					time: '',
					showTime: '',
					calendar: []
				},
				headerData: [
					{
						value: '日',
					},
					{
						value: '一',
					},
					{
						value: '二',
					},
					{
						value: '三',
					},
					{
						value: '四',
					},
					{
						value: '五',
					},
					{
						value: '六',
					}
				]
			};
		},
		props: {
		  time: { // 是否展示弹框 值为布尔值，此时没规定type，是未避免warn
				default: new Date()
		  },
			isShow: {
				type: Boolean,
				required: true
			}
		},
		watch: {
			time: {
				handler(newVal) {
					this.dealDate(new Date(newVal))
				},
				immediate: true
			}
		},
		methods: {
			// 数据点击-不可点击数据
			noClickData() {
				uni.showToast({
					icon: 'none',
					title: '该日期不可点击'
				})
			},
			// 数据点击-可点击数据
			clickData(item, index){
				this.$set(this.dataObj.calendar[index], 'active', !item.active)
				this.dealClickData()
			},
			// 处理当前选中的所有数据
			dealClickData() {
				let clickData = this.dataObj.calendar.filter(inner => inner.active)
				this.$emit('change', clickData)
			},
			// 数据处理
			dealDate (time) {
				let timeStr = new Date(time)
				this.$set(this.dataObj, 'time', timeStr)
				this.$set(this.dataObj, 'showTime', this.dateFtt('yyyy年MM月', timeStr))
				let oneDayTime = 3600 * 24 * 1000
				let firstDayStamp = new Date(`${timeStr.getFullYear()}/${timeStr.getMonth()+1}/01`)
				let lastDayStamp = new Date(`${timeStr.getFullYear()}/${timeStr.getMonth()+2}/01`) - oneDayTime
				let prevTime = this.dealPrev(firstDayStamp)
				let nextTime = this.dealNext(lastDayStamp)
				let monthTime = this.dealMonth(lastDayStamp)
				this.$set(this.dataObj, 'calendar', [...prevTime, ...monthTime, ...nextTime])
			},
			// 处理月初数据-不可点击
			dealPrev(firstDayStamp) {
				let oneDayTime = 3600 * 24 * 1000
				// let firstDayStamp = new Date(`${time.getFullYear()}/${time.getMonth()+1}/01`)
				let firstDay = new Date(firstDayStamp)
				let days1 = firstDay.getDay()
				if (days1 > 0) {
					let prevTime = new Array(days1 - 1).fill(null).map((inner, innerIndex) => {
						let timeStamp = firstDay.getTime() - (days1 - innerIndex - 1) * oneDayTime
						let time = new Date(timeStamp)
						return {
							time: time,
							showTime: this.dateFtt('yyyy年MM月dd日', time),
							day: time.getDate(),
							placeholder: true
						}
					})
					return prevTime
				}
				return []
			},
			// 处理月末数据-不可点击
			dealNext(lastDayStamp) {
				let oneDayTime = 3600 * 24 * 1000
				// let lastDayStamp = new Date(`${time.getFullYear()}/${time.getMonth()+2}/01`) - oneDayTime
				let lastDay = new Date(lastDayStamp)
				let days2 = lastDay.getDay()
				if (days2 > 0) {
					let nextTime = new Array(7 - days2).fill(null).map((inner, innerIndex) => {
						let timeStamp = lastDay.getTime() + (innerIndex + 1) * oneDayTime
						let time = new Date(timeStamp)
						return {
							time: time,
							showTime: this.dateFtt('yyyy年MM月dd日', time),
							day: time.getDate(),
							placeholder: true
						}
					})
					return nextTime
				}
				return []
			},
			// 处理本月真实数据
			dealMonth(lastDayStamp) {
				let lastDay = new Date(lastDayStamp)
				let year = lastDay.getFullYear()
				let month = lastDay.getMonth() + 1
				let date = lastDay.getDate()
				let monthTime = new Array(date).fill(null).map((item, index) => {
					let time = new Date(`${year}/${month}/${index+1}`)
					return {
						time: time,
						showTime: this.dateFtt('yyyy年MM月dd日', time),
						day: time.getDate(),
						redDot: [2, 4, 6].includes(time.getDay())
					}
				})
				return monthTime
			},
			// 对时间进行格式化 如 dateFtt("yyyy-MM-dd hh:mm:ss",crtTime)
			dateFtt(fmt, date) {
				var o = {
					'M+': date.getMonth() + 1, // 月份
					'd+': date.getDate(), // 日
					'h+': date.getHours(), // 小时
					'm+': date.getMinutes(), // 分
					's+': date.getSeconds(), // 秒
					'q+': Math.floor((date.getMonth() + 3) / 3), // 季度
					'S': date.getMilliseconds() // 毫秒
				}
				if (/(y+)/.test(fmt)) {
					fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
				}
				for (var k in o) {
					if (new RegExp('(' + k + ')').test(fmt)) {
						fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k])
							.length)))
					}
				}
				return fmt
			}
		}
	}
</script>

<style lang="scss" scoped>
	.calendarWrap{
		width: 100%;
		background-color: #fff;
		border-radius: 20rpx;
		text{
			display: inline-block;
			line-height: 36rpx;
			color: #072959;
		}
		.top{
			width: 100%;
			display: flex;
			align-items: center;
			justify-content: space-between;
			.prev, .next{
				width: 40rpx;
				height: 40rpx;
				background-color: #aec2d5;
				border-radius: 50%;
				margin: 30rpx;
				box-sizing: content-box;
			}
			text{
				font-size: 26rpx;
				font-weight: bold;
			}
		}
		.dateWrap{
			.header, .content{
				width: 100%;
				display: flex;
				flex-wrap: wrap;
				.block{
					width: 14.28%;
					height: 60rpx;
					display: flex;
					align-content: center;
					justify-content: center;
					&.placeholder{
						text{
							color: #ced2e8;
						}
					}
					&.redDot{
						position: relative;
						&::after{
							content: '';
							width: 8rpx;
							height: 8rpx;
							border-radius: 50%;
							position: absolute;
							bottom: 16rpx;
							left: 50%;
							transform: translateX(-50%);
							background-color: #9bd38f;
						}
					}
					&.isActive{
						position: relative;
						text{
							color: #fff;
							position: relative;
							z-index: 1;
						}
						&::before{
							content: '';
							width: 36rpx;
							height: 36rpx;
							border-radius: 50%;
							position: absolute;
							top: 0;
							left: 50%;
							transform: translateX(-50%);
							background-color: #072959;
							z-index: 0;
						}
					}
				}
			}
		}
	}
</style>